
//Copyright 1997-2009 Syrinx Development, Inc.
//This file is part of the Syrinx Web Application Framework (SWAF).
// == BEGIN LICENSE ==
//
// Licensed under the terms of any of the following licenses at your
// choice:
//
//  - GNU General Public License Version 3 or later (the "GPL")
//    http://www.gnu.org/licenses/gpl.html
//
//  - GNU Lesser General Public License Version 3 or later (the "LGPL")
//    http://www.gnu.org/licenses/lgpl.html
//
//  - Mozilla Public License Version 1.1 or later (the "MPL")
//    http://www.mozilla.org/MPL/MPL-1.1.html
//
// == END LICENSE ==
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

using Swaf;
using Swaf.Gui;
using Swaf.Gui.AspNet2;

namespace Syrinx.Gui.AspNet.Ajax
{
	public class CalendarBizObjListDisplay : Calendars.Gui.AspNet.BizObjListCalendar, IAjaxClientControl
	{
		protected static string s_setupScript = @"
<script>
var cc = new ClientControl(document.getElementById('{0}'), setCalendarState, getCalendarState);
cc.id = '{0}';
{1}BizProc.addClientControl(cc);
</script>
";
		protected static string s_globalScript = @"
function getCalendarState(stateEl)
{
}
";

		public CalendarBizObjListDisplay() : base() { }
		public CalendarBizObjListDisplay(ActiveWidget widget) : base(widget) { }


		protected override string getCellClickEventHandler(DateTime date)
		{
			string pInfo = date.ToShortDateString();
			string script = "";
			if (!Cmn.IsEmpty(OnDateClick))
				script += OnDateClick;
			if (Page is INitobiPage || (Page is NitobiBasePage && ((NitobiBasePage)Page).UsingAjax))
			{
				ActiveBizProc bizproc = BPC.getActiveBizProc(State.ParentBizProcIds[0]);
				script += string.Format(@"{0}BizProc.triggerEvent('{1}','DateSelected','{2}');", bizproc.BizProc.Id, WidgetId, pInfo);
			}
			else
				script += base.getCellClickEventHandler(date);


			return script;
		}


		protected override void OnPreRender(EventArgs e)
		{
			base.OnPreRender(e);
			if (Page is INitobiPage || (Page is NitobiBasePage && ((NitobiBasePage)Page).UsingAjax))
				Page.ClientScript.RegisterClientScriptBlock(GetType(), "Global", s_globalScript, true);
		}

		protected Calendars.Gui.CalendarViewBizProc CalProc
		{
			get
			{
				string parentBizProcId = null;
				ActiveBizProc bizproc = null;

				if (State.ParentBizProcIds != null && State.ParentBizProcIds.Count > 0)
					parentBizProcId = State.ParentBizProcIds[0];
				if (parentBizProcId != null)
					bizproc = BPC.getActiveBizProc(parentBizProcId);
				if (bizproc == null)
					throw new BaseException(string.Format("Cannot find parent bizproc for bizObjListDisplay {0} using parent id of {1}", WidgetId, parentBizProcId));
				return bizproc.BizProc as Calendars.Gui.CalendarViewBizProc;
			}
		}

		/// <summary>
		/// Renders the calendar html with additional script and comment markets
		/// </summary>
		/// <param name="writer"></param>
		/// <remarks>The only reason a nitobi based control should need to override render is because it needs its
		/// parent control to render during ajax events and it will grab the html and script from the page output
		/// to be sent down in the ajax response.  If the control can generate its html/scripts independantly of the
		/// render process then it could be called directly from getState rather than going this route.</remarks>
		protected override void Render(System.Web.UI.HtmlTextWriter writer)
		{
			Calendars.Gui.CalendarViewBizProc bizproc = CalProc;
			if (!bizproc.IsSelectEvent || !IsInFlow)
			{
				bool usingAjax = (Page is INitobiPage || (Page is NitobiBasePage && ((NitobiBasePage)Page).UsingAjax));
				if (usingAjax)
					writer.Write("<!--{0}-->", ClientID);

				base.Render(writer);

				if (usingAjax)
				{

					writer.Write(s_setupScript, ClientID, bizproc.Id);
					writer.Write("<!--{0}-->", ClientID);
				}
			}
		}

		#region IAjaxClientControl Members
		bool m_createActiveOnLoad = true;
		public bool CreateOnLoad { set { m_createActiveOnLoad = value; } }


		public void setState(System.Xml.XmlElement clientState)
		{
		}

		public void getState(System.Xml.XmlElement clientState, string pageHtml)
		{
			Calendars.Gui.CalendarViewBizProc bizproc = CalProc;
			if (pageHtml != null && (!bizproc.IsSelectEvent || !IsInFlow))
			{
				StringWriter sw = new StringWriter();
				m_writer = new System.Web.UI.HtmlTextWriter(sw);
				StringBuilder scriptBuff = new StringBuilder();
				string myHtml = ViewBody + sw;
				//Regex r = new Regex(string.Format("<!--{0}-->(.*?)<!--{0}-->", ClientID.Replace("$", "\\$")), RegexOptions.IgnoreCase | RegexOptions.Singleline);
				//Match m = r.Match(pageHtml);
				//if (m.Success)
				{
					StringBuilder htmlBuff = new StringBuilder();
					//string myHtml = m.Groups[1].Value;
					Regex r = new Regex("<script.*?>(.*?)</script>", RegexOptions.IgnoreCase | RegexOptions.Singleline);
					MatchCollection mc = r.Matches(myHtml);
					int lastPos = 0;
					foreach (Match m2 in mc)
					{
						htmlBuff.Append(myHtml.Substring(lastPos, m2.Index - lastPos));
						scriptBuff.Append(m2.Groups[1].Value);
						lastPos = m2.Index + m2.Length;
					}
					//if (lastPos != 0)
					htmlBuff.Append(myHtml.Substring(lastPos));
					scriptBuff.AppendFormat("\r\nsetup{0}Blocks();", WidgetId);

					sw.GetStringBuilder().Length = 0;
					clientState.SetAttribute("title", ViewTitle + sw);
					clientState.SetAttribute("body", htmlBuff.ToString());
					clientState.SetAttribute("script", scriptBuff.ToString());
				}
			}
		}

		public void processAjaxEvent(System.Xml.XmlElement eventInfo)
		{
			string action = eventInfo.GetAttribute("event");

			//Getting bizproc is just so it gets activated and processed.
			Calendars.Gui.CalendarViewBizProc bizproc = CalProc;
			DateTime selDate = DateTime.Parse(eventInfo.GetAttribute("value"));
			bizproc.IsSelectEvent = true;
			bizproc.selectDate(selDate);

		}

		public bool NeedToGenerateHtmlWithServerControls
		{
			get { return true; }
		}

		#endregion

		//protected override string genPostBack(string pInfo)
		//{
		//    if (Page is INitobiPage || (Page is NitobiBasePage && ((NitobiBasePage)Page).UsingAjax))
		//    {
		//        ActiveBizProc bizproc = BPC.getActiveBizProc(State.ParentBizProcIds[0]);
		//        return string.Format(@"{0}BizProc.triggerEvent('{1}','{2}');", bizproc.BizProc.Id, WidgetId, pInfo);
		//    }
		//    else
		//        return base.genPostBack(pInfo);
		//}
	}
}
